import { download } from '@/utils/common';
export { templateEngine } from '@/views/tool/build/components/util';

/**
 * 页面生成模板
 */
export const indexTemplate = `<template>
  <ele-page>
    <!-- 搜索表单 -->
    <<% d.modelName %>-search @search="reload" />
    <ele-card :body-style="{ paddingTop: '8px' }">
      <!-- 表格 -->
      <ele-pro-table
        ref="tableRef"
        row-key="<% d.primaryKey %>"
        :columns="columns"
        :datasource="datasource"
        :show-overflow-tooltip="true"
        v-model:selections="selections"
        highlight-current-row
        cache-key="<% d.tableCacheKey %>"
      >
        <template #toolbar>
          <el-button
            type="primary"
            class="ele-btn-icon"
            :icon="PlusOutlined"
            @click="openEdit()"
          >
            新建
          </el-button>
          <el-button
            type="danger"
            class="ele-btn-icon"
            :icon="DeleteOutlined"
            @click="removeBatch()"
          >
            删除
          </el-button>
          <el-button class="ele-btn-icon" :icon="DownloadOutlined" @click="exportData">
            导出
          </el-button>
        </template>
        <template #action="{ row }">
          <el-link type="primary" :underline="false" @click="openEdit(row)">
            修改
          </el-link>
          <el-divider direction="vertical" />
          <el-link type="danger" :underline="false" @click="removeBatch(row)">
            删除
          </el-link>
        </template><%# d.columns.forEach(function(item){if(item.dictType){ %>
        <template #<% item.prop %>="{ row }">
          <dict-data
            code="<% item.dictType %>"
            type="tag"
            :model-value="row.<% item.prop %>"
          />
        </template><%# }}); %>
      </ele-pro-table>
    </ele-card>
    <!-- 编辑弹窗 -->
    <<% d.modelName %>-edit v-model="showEdit" :data="current" @done="reload" />
  </ele-page>
</template>

<script setup>
  import { ref } from 'vue';
  import {
    PlusOutlined,
    DeleteOutlined,
    DownloadOutlined
  } from '@/components/icons';
  import { ElMessageBox } from 'element-plus/es';
  import { EleMessage } from 'ele-admin-plus/es';
  import <% d.modelTypeName %>Search from './components/<% d.modelName %>-search.vue';
  import <% d.modelTypeName %>Edit from './components/<% d.modelName %>-edit.vue';
  import { page<% d.modelTypeName %>s, remove<% d.modelTypeName %>s, export<% d.modelTypeName %>s } from '@/api/<% d.moduleName %>/<% d.modelName %>';

  /** 表格实例 */
  const tableRef = ref(null);

  /** 表格列配置 */
  const columns = ref([
    {
      type: 'selection',
      columnKey: 'selection',
      width: 50,
      align: 'center',
      fixed: 'left'
    },
    {
      type: 'index',
      columnKey: 'index',
      width: 50,
      align: 'center',
      fixed: 'left'
    }<%# d.columns.forEach(function (item){ %>,
    {
      prop: '<% item.prop %>',
      label: '<% item.label %>',
      align: 'center',
      minWidth: 110<%# if(item.dictType){ %>,
      slot: '<% item.prop %>'<%# } %>
    }<%# }); %>,
    {
      columnKey: 'action',
      label: '操作',
      width: 180,
      align: 'center',
      slot: 'action'
    }
  ]);

  /** 表格选中数据 */
  const selections = ref([]);

  /** 当前编辑数据 */
  const current = ref(null);

  /** 是否显示编辑弹窗 */
  const showEdit = ref(false);

  /** 表格数据源 */
  const datasource = ({ pages, where }) => {
    return page<% d.modelTypeName %>s({ ...where, ...pages });
  };

  /** 搜索 */
  const reload = (where) => {
    tableRef.value?.reload?.({ page: 1, where });
  };

  /** 打开编辑弹窗 */
  const openEdit = (row) => {
    current.value = row ?? null;
    showEdit.value = true;
  };

  /** 批量删除 */
  const removeBatch = (row) => {
    const rows = row == null ? selections.value : [row];
    if (!rows.length) {
      EleMessage.error('请至少选择一条数据');
      return;
    }
    ElMessageBox.confirm(
      \`是否确认删除<% d.delTipName %>为"\${rows.map((d) => d.<% d.delTipKey %>).join()}"的数据项?\`,
      '系统提示',
      { type: 'warning', draggable: true }
    )
      .then(() => {
        const loading = EleMessage.loading('请求中..');
        remove<% d.modelTypeName %>s(rows.map((d) => d.<% d.primaryKey %>))
          .then(() => {
            loading.close();
            EleMessage.success('删除成功');
            reload();
          })
          .catch((e) => {
            loading.close();
            EleMessage.error(e.message);
          });
      })
      .catch(() => {});
  };

  /** 导出数据 */
  const exportData = () => {
    const loading = EleMessage.loading('请求中..');
    tableRef.value?.fetch?.(({ where }) => {
      export<% d.modelTypeName %>s(where)
        .then(() => {
          loading.close();
        })
        .catch((e) => {
          loading.close();
          EleMessage.error(e.message);
        });
    });
  };
</script>
`;

/**
 * 搜索表单生成模板
 */
export const searchTemplate = `<template>
  <ele-card :body-style="{ paddingBottom: '2px' }">
    <el-form label-width="72px" @keyup.enter="search" @submit.prevent="">
      <el-row :gutter="8"><%# d.queryForm.forEach(function(item){ %>
        <el-col :lg="6" :md="12" :sm="12" :xs="24">
          <el-form-item label="<% item.label %>">
            <%# if(item.dictType){ %><dict-data
              code="<% item.dictType %>"
              v-model="form.<% item.prop %>"
              placeholder="请选择"
            /><%# }else{ %><el-input
              clearable
              v-model.trim="form.<% item.prop %>"
              placeholder="请输入"
            /><%# } %>
          </el-form-item>
        </el-col><%# }); %>
        <el-col :lg="6" :md="12" :sm="12" :xs="24">
          <el-form-item label-width="16px">
            <el-button type="primary" @click="search">查询</el-button>
            <el-button @click="reset">重置</el-button>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </ele-card>
</template>

<script setup>
  import { useFormData } from '@/utils/use-form-data';

  const emit = defineEmits(['search']);

  /** 表单数据 */
  const [form, resetFields] = useFormData({<%# d.queryForm.forEach(function(item, i){ %>
    <% item.prop %>: <% item.isString ? "''" : 'void 0' %><% i === (d.queryForm.length - 1) ? '' : ',' %><%# }); %>
  });

  /** 搜索 */
  const search = () => {
    emit('search', { ...form });
  };

  /**  重置 */
  const reset = () => {
    resetFields();
    search();
  };
</script>
`;

/**
 * 编辑弹窗生成模板
 */
export const editTemplate = `<!-- 编辑弹窗 -->
<template>
  <ele-modal
    form
    :width="460"
    :model-value="modelValue"
    :title="isUpdate ? '修改<% d.modelText %>' : '添加<% d.modelText %>'"
    @update:modelValue="updateModelValue"
  >
    <el-form
      ref="formRef"
      :model="form"
      :rules="rules"
      label-width="80px"
      @submit.prevent=""
    ><%# d.editForm.forEach(function(item){ %>
      <el-form-item label="<% item.label %>" prop="<% item.prop %>">
        <%# if(item.dictType){ %><dict-data
          code="<% item.dictType %>"<%# if(['radio','checkbox'].includes(item.formType)){ %>
          type="<% item.formType %>"<%# } %>
          v-model="form.<% item.prop %>"
        /><%# }else if(item.formType==='textarea'){ %><el-input
          :rows="4"
          type="textarea"
          v-model="form.<% item.prop %>"
          placeholder="请输入<% item.label %>"
        /><%# }else if(item.formType==='datetime'){ %><el-date-picker
          v-model="form.<% item.prop %>"
          value-format="YYYY-MM-DD"
          placeholder="请选择<% item.label %>"
          class="ele-fluid"
        /><%# }else{ %><el-input
          clearable
          v-model="form.<% item.prop %>"
          placeholder="请输入<% item.label %>"
        /><%# } %>
      </el-form-item><%# }); %>
    </el-form>
    <template #footer>
      <el-button @click="updateModelValue(false)">取消</el-button>
      <el-button type="primary" :loading="loading" @click="save">
        保存
      </el-button>
    </template>
  </ele-modal>
</template>

<script setup>
  import { ref, reactive, watch } from 'vue';
  import { EleMessage } from 'ele-admin-plus/es';
  import { useFormData } from '@/utils/use-form-data';
  import { add<% d.modelTypeName %>, update<% d.modelTypeName %> } from '@/api/<% d.moduleName %>/<% d.modelName %>';

  const emit = defineEmits(['done', 'update:modelValue']);

  const props = defineProps({
    /** 弹窗是否打开 */
    modelValue: Boolean,
    /** 修改回显的数据 */
    data: Object
  });

  /** 是否是修改 */
  const isUpdate = ref(false);

  /** 提交状态 */
  const loading = ref(false);

  /** 表单实例 */
  const formRef = ref(null);

  /** 表单数据 */
  const [form, resetFields, assignFields] = useFormData({
    <% d.primaryKey %>: void 0<%# d.editForm.forEach(function(item){ %>,
    <% item.prop %>: <% item.isString ? "''" : 'void 0' %><%# }); %>
  });

  /** 表单验证规则 */
  const rules = reactive({<%# d.editRules.forEach(function(item,i){ %>
    <% item.prop %>: [
      {
        required: true,
        message: '请输入<% item.label %>',
        type: '<% item.type %>',
        trigger: '<% item.trigger %>'
      }
    ]<% i === (d.editRules.length - 1) ? '' : ',' %><%# }); %>
  });

  /** 保存编辑 */
  const save = () => {
    formRef.value?.validate?.((valid) => {
      if (!valid) {
        return;
      }
      loading.value = true;
      const saveOrUpdate = isUpdate.value ? update<% d.modelTypeName %> : add<% d.modelTypeName %>;
      saveOrUpdate(form)
        .then((msg) => {
          loading.value = false;
          EleMessage.success(msg);
          updateModelValue(false);
          emit('done');
        })
        .catch((e) => {
          loading.value = false;
          EleMessage.error(e.message);
        });
    });
  };

  /** 更新modelValue */
  const updateModelValue = (value) => {
    emit('update:modelValue', value);
  };

  watch(
    () => props.modelValue,
    (modelValue) => {
      if (modelValue) {
        if (props.data) {
          assignFields(props.data);
          isUpdate.value = true;
        } else {
          isUpdate.value = false;
        }
      } else {
        resetFields();
        formRef.value?.clearValidate?.();
      }
    }
  );
</script>
`;

/**
 * 接口生成模板
 */
export const apiTemplate = `import request from '@/utils/request';
import { download, toFormData, checkDownloadRes } from '@/utils/common';

/**
 * 分页查询<% d.modelText %>
 */
export async function page<% d.modelTypeName %>s(params) {
  const res = await request.get('/<% d.moduleName %>/<% d.modelName %>/list', { params });
  if (res.data.code === 200) {
    return res.data;
  }
  return Promise.reject(new Error(res.data.msg));
}

/**
 * 添加<% d.modelText %>
 */
export async function add<% d.modelTypeName %>(data) {
  const res = await request.post('/<% d.moduleName %>/<% d.modelName %>', data);
  if (res.data.code === 200) {
    return res.data.msg;
  }
  return Promise.reject(new Error(res.data.msg));
}

/**
 * 修改<% d.modelText %>
 */
export async function update<% d.modelTypeName %>(data) {
  const res = await request.put('/<% d.moduleName %>/<% d.modelName %>', data);
  if (res.data.code === 200) {
    return res.data.msg;
  }
  return Promise.reject(new Error(res.data.msg));
}

/**
 * 删除<% d.modelText %>
 */
export async function remove<% d.modelTypeName %>(id) {
  const res = await request.delete('/<% d.moduleName %>/<% d.modelName %>/' + id);
  if (res.data.code === 200) {
    return res.data.msg;
  }
  return Promise.reject(new Error(res.data.msg));
}

/**
 * 批量删除<% d.modelText %>
 */
export async function remove<% d.modelTypeName %>s(ids) {
  const res = await request.delete('/<% d.moduleName %>/<% d.modelName %>/' + ids.join());
  if (res.data.code === 200) {
    return res.data.msg;
  }
  return Promise.reject(new Error(res.data.msg));
}

/**
 * 导出<% d.modelText %>
 */
export async function export<% d.modelTypeName %>s(params) {
  const res = await request({
    url: '/<% d.moduleName %>/<% d.modelName %>/export',
    method: 'POST',
    data: toFormData(params),
    responseType: 'blob'
  });
  await checkDownloadRes(res);
  download(res.data, \`<% d.modelName %>_\${Date.now()}.xlsx\`);
}
`;

/**
 * 获取模板数据
 * @param res 接口数据
 */
export function getTemplateData(res) {
  const primaryField = {};
  const columns = [];
  const queryForm = [];
  const editForm = [];
  const editRules = [];
  res.info.columns.forEach((col) => {
    if (col.isPk == '1') {
      primaryField.prop = col.javaField;
      primaryField.label = col.columnComment;
    }
    if (col.isList == '1') {
      columns.push({
        prop: col.javaField,
        label: col.columnComment,
        dictType: col.dictType
      });
    }
    if (col.isQuery == '1') {
      queryForm.push({
        prop: col.javaField,
        label: col.columnComment,
        dictType: col.dictType,
        isString: ['String', 'Date'].includes(col.javaType)
      });
    }
    if (col.isEdit == '1') {
      editForm.push({
        prop: col.javaField,
        label: col.columnComment,
        dictType: col.dictType,
        formType: col.htmlType,
        isString: ['String', 'Date'].includes(col.javaType)
      });
      if (col.isRequired == '1') {
        editRules.push({
          prop: col.javaField,
          label: col.columnComment,
          type: ['String', 'Date'].includes(col.javaType) ? 'string' : 'number',
          trigger: [
            'select',
            'radio',
            'checkbox',
            'imageUpload',
            'fileUpload',
            'editor'
          ].includes(col.htmlType)
            ? 'change'
            : 'blur'
        });
      }
    }
  });
  const moduleName = res.info.moduleName;
  const modelTypeName = capitalizeStr(res.info.businessName);
  const primaryKey = primaryField.prop || 'key';
  const firstColumn = columns.length ? columns[0] : primaryField;
  return {
    modelName: res.info.businessName, // 模型名
    modelTypeName, // 模型类型名
    modelText: res.info.functionName, // 模型显示文本
    primaryKey, // 主键名
    moduleName, // 模块名
    tableCacheKey: moduleName + modelTypeName + 'Table', // 表格缓存名
    columns, // 表格列
    delTipKey: firstColumn.prop || primaryKey, // 删除提示字段名
    delTipName: firstColumn.label || '', // 删除提示文本名
    queryForm, // 搜索表单
    editForm, // 编辑表单
    editRules // 编辑表单验证规则
  };
}

/**
 * 字符串首字母大写
 * @param str 字符串
 */
export function capitalizeStr(str) {
  if (str == null || str === '') {
    return '';
  }
  return str.charAt(0).toUpperCase() + str.slice(1);
}

/**
 * 下载文本
 * @param text 文本内容
 * @param name 文件名称
 */
export function downloadText(text, name) {
  download(text, name, 'text/plain;charset=utf-8');
}
